package ui;

import java.awt.Dimension;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.*;
import java.util.Date;

import javax.media.opengl.GLCanvas;

import settings.Settings;
import ui.timeline.TimeLine;
import model.MainModel;

import com.sun.opengl.util.Animator;

import experiment.EventLogger;
import experiment.Experiment;
import experiment.ExperimentManager;
import graphics.engine.*;


public class MainWindow {

	private static Frame frame;
	private static GLCanvas leftCanvas;
	private static GLCanvas rightCanvas;
	private static TimeLine timeLine;
	private static Animator animator;
	private static MainModel model;
	
	public static void main(String[] args) 
	{			
		if(Settings.isExperimentMode)
		{
			ParticipantDialog dialog = new ParticipantDialog();
			dialog.setVisible(true);
		}
		else
		{
			MainWindow.model = new MainModel();
			
			Date launchTime = new Date(System.currentTimeMillis());
			GridBagLayout layout = new GridBagLayout();
			
			frame = new Frame("FloorPlan NodeLink Hybrid Prototype");
			frame.setLayout(layout);
			
			GridBagConstraints c = new GridBagConstraints();
			c.fill = GridBagConstraints.BOTH;
			c.gridx = 0;
			c.gridy = 1;
			c.gridwidth = 3;
			c.gridheight = 1;
			c.weightx = 1.0f;
			c.weighty = 1.0f;

			timeLine = new TimeLine(new Date(System.currentTimeMillis()), new Date(model.minTime), new Date(model.maxTime ));
				
			frame.add(timeLine, c);
			
			
			leftCanvas = new GLCanvas();
			RenderEngine leftRenderEngine;
			
			c = new GridBagConstraints();
			c.fill = GridBagConstraints.VERTICAL;
			c.anchor = GridBagConstraints.EAST;
			c.gridx = 0;
			c.gridy = 0;
			c.weightx = 1;
			c.weighty = 1;
			c.gridwidth = 1;
			c.gridheight = 1;
			
			TargetGrid grid = new TargetGrid(model.targets);
			grid.setSize(new Dimension(Settings.GridWidth, Settings.CanvasHeight));
			grid.setMinimumSize(new Dimension(Settings.GridWidth, Settings.CanvasHeight));
			grid.setPreferredSize(new Dimension(Settings.GridWidth, Settings.CanvasHeight));
			grid.setMaximumSize(new Dimension(Settings.GridWidth, Settings.CanvasHeight));
			
			frame.add(grid,c);
			
			if(Settings.IsHybrid)
			{
				c = new GridBagConstraints();
				c.fill = GridBagConstraints.BOTH;
				c.anchor = GridBagConstraints.EAST;
				c.gridx = 1;
				c.gridy = 0;
				c.weightx = 20;
				c.weighty = 20;
				c.gridwidth = 2;
				c.gridheight = 1;
				leftRenderEngine = new RenderEngine(model, timeLine, launchTime);
			}
			else
			{		
				c = new GridBagConstraints();
				c.fill = GridBagConstraints.BOTH;
				c.anchor = GridBagConstraints.EAST;
				c.gridx = 1;
				c.gridy = 0;
				c.weightx = 10;
				c.weighty = 1;
				c.gridwidth = 1;
				c.gridheight = 1;
				leftRenderEngine = new RenderEngine(model, timeLine, launchTime);
			}
			
			leftCanvas.addGLEventListener(leftRenderEngine);
			leftCanvas.addKeyListener(leftRenderEngine.getKeyboardControler());
			leftCanvas.addMouseListener(leftRenderEngine.getMouseControler());
			leftCanvas.addMouseMotionListener(leftRenderEngine.getMouseControler());
			leftCanvas.addMouseWheelListener(leftRenderEngine.getMouseControler());
	
			
			frame.add(leftCanvas, c);
			
			if(!Settings.IsHybrid)
			{
				c = new GridBagConstraints();
				c.fill = GridBagConstraints.BOTH;
				c.anchor = GridBagConstraints.EAST;
				c.gridx = 2;
				c.gridy = 0;
				c.weightx = 0.5;
				c.weighty = 1;
				c.gridwidth = 1;
				
				rightCanvas = new GLCanvas();
				RenderEngine rightRenderEngine = new RenderEngine(model, timeLine, launchTime);
				
				rightCanvas.addGLEventListener(rightRenderEngine);
				rightCanvas.addKeyListener(rightRenderEngine.getKeyboardControler());
				rightCanvas.addMouseListener(rightRenderEngine.getMouseControler());
				rightCanvas.addMouseMotionListener(rightRenderEngine.getMouseControler());
				rightCanvas.addMouseWheelListener(rightRenderEngine.getMouseControler());
				
				frame.add(rightCanvas, c);
			}
			
			animator = new Animator(leftCanvas);
			
			frame.addWindowListener(new WindowAdapter() 
			{
				public void windowClosing(WindowEvent e)
				{
					new Thread(new Runnable() 
					{
						public void run() 
						{
							animator.stop();
							System.exit(0);
						}
					}).start();
				}
			});

			frame.setExtendedState(Frame.MAXIMIZED_BOTH);
			frame.setState(Frame.MAXIMIZED_BOTH);
			frame.setVisible(true);
			 
			if(!Settings.IsHybrid)
			{
				animator.add(rightCanvas);
			}
		    animator.start();

			frame.setVisible(true);
		}
		

	    
	}

	public static Frame getFrame() {
		// TODO Auto-generated method stub
		return MainWindow.frame;
	}


	public static void loadExperiment(int participantID) {
		// TODO Auto-generated method stub
		MainWindow.model = new MainModel();
		
		Date launchTime = new Date(System.currentTimeMillis());
		GridBagLayout layout = new GridBagLayout();
		
		frame = new Frame("FloorPlan NodeLink Hybrid Prototype");
		frame.setLayout(layout);
		
		GridBagConstraints c = new GridBagConstraints();
		c.fill = GridBagConstraints.BOTH;
		c.gridx = 0;
		c.gridy = 1;
		c.gridwidth = 3;
		c.gridheight = 1;
		c.weightx = 1.0f;
		c.weighty = 1.0f;

		timeLine = new TimeLine(new Date(System.currentTimeMillis()), new Date(model.minTime), new Date(model.maxTime ));
			
		frame.add(timeLine, c);
		
		
		leftCanvas = new GLCanvas();
		RenderEngine leftRenderEngine = new RenderEngine(model, timeLine, launchTime);
		
		
		ExperimentManager experimentManager = new ExperimentManager(leftRenderEngine, participantID);
		Experiment experiment = experimentManager.getExperiment();
		EventLogger eventLogger = new EventLogger(experimentManager);
		
		
		leftCanvas.addGLEventListener(leftRenderEngine);
		leftCanvas.addKeyListener(leftRenderEngine.getKeyboardControler());
		leftCanvas.addMouseListener(leftRenderEngine.getMouseControler());
		leftCanvas.addMouseMotionListener(leftRenderEngine.getMouseControler());
		leftCanvas.addMouseWheelListener(leftRenderEngine.getMouseControler());
	
		frame.addKeyListener(eventLogger);
		frame.addMouseListener(eventLogger);
		frame.addMouseMotionListener(eventLogger);
		frame.addMouseWheelListener(eventLogger);


		leftCanvas.addKeyListener(eventLogger);
		leftCanvas.addMouseListener(eventLogger);
		leftCanvas.addMouseMotionListener(eventLogger);
		leftCanvas.addMouseWheelListener(eventLogger);

		timeLine.addChangeListener(eventLogger);
		timeLine.addMouseListener(eventLogger);
		timeLine.addMouseMotionListener(eventLogger);
		
		
		c = new GridBagConstraints();
		c.fill = GridBagConstraints.BOTH;
		c.anchor = GridBagConstraints.EAST;
		c.gridx = 1;
		c.gridy = 0;
		c.weightx = 1;
		c.weighty = 1;
		c.gridwidth = 2;
		c.gridheight = 1;
		frame.add(leftCanvas, c);
		
		
		animator = new Animator(leftCanvas);
		
		frame.addWindowListener(new WindowAdapter() 
		{
			public void windowClosing(WindowEvent e)
			{
				new Thread(new Runnable() 
				{
					public void run() 
					{
						animator.stop();
						System.exit(0);
					}
				}).start();
			}
		});
		
		frame.setExtendedState(Frame.MAXIMIZED_BOTH);
		frame.setState(Frame.MAXIMIZED_BOTH);
	
	    animator.start();
		frame.setVisible(true);	
		
		QuestionsPanel questionsPanel = new QuestionsPanel(experimentManager);
		
		c = new GridBagConstraints();
		c.fill = GridBagConstraints.BOTH;
		c.anchor = GridBagConstraints.EAST;
		c.gridx = 0;
		c.gridy = 0;
		c.weightx = 1;
		c.weighty = 1;
		c.gridwidth = 1;
		c.gridheight = 1;
		frame.add(questionsPanel, c);
		
		experimentManager.startExperiment();
	}
}